package com.atguigu.test.lifecycle;

import com.atguigu.test.annotation.MyComponent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author zp
 * @version 1.0
 * @description: 自定义实例化Aware感知Bean后处理器
 * @date 2022/11/30 18:42
 */
@Component
@Slf4j
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

    /**
     * @param beanClass
     * @param beanName
     * @return Object
     * @description: 实例化之前 增强
     * @author zp
     * @date: 2022/11/30 18:45
     */
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        return InstantiationAwareBeanPostProcessor.super.postProcessBeforeInstantiation(beanClass, beanName);
    }

    /**
     * @param bean
     * @param beanName
     * @return boolean
     * @description: 是否经历实例化之前的增强
     * @author zp
     * @date: 2022/11/30 18:47
     */
    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        return InstantiationAwareBeanPostProcessor.super.postProcessAfterInstantiation(bean, beanName);
    }

    /**
     * @param pvs
     * @param bean
     * @param beanName
     * @return PropertyValues
     * @description: 实例化之后 增强
     * @author zp
     * @date: 2022/11/30 18:47
     */
    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        Annotation[] annotations = bean.getClass().getAnnotations();
        MyComponent myComponent = null;
        for (Annotation annotation : annotations) {
            if (annotation instanceof MyComponent) {
                myComponent = (MyComponent) annotation;
            }
        }

        if (myComponent != null) {
            try {
                Method setBeanName = bean.getClass().getMethod("setIdName", String.class);
                setBeanName.invoke(bean, myComponent.value());
                log.info("InstantiationAwareBeanPostProcessor 》》》 处理之前 执行");
            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                throw new RuntimeException(e);
            }
            log.info("InstantiationAwareBeanPostProcessor 》》》 postProcessProperties执行结束");
        }


        return InstantiationAwareBeanPostProcessor.super.postProcessProperties(pvs, bean, beanName);
    }
}
